Fix support of `[target.'cfg(...)']` syntax for rustc and rustdoc flags
authortee-too <tee-too@users.noreply.github.com>
Thu, 13 Jul 2017 11:24:28 +0000 (13:24 +0200)
committertee-too <tee-too@users.noreply.github.com>
Thu, 13 Jul 2017 13:49:35 +0000 (15:49 +0200)
Support of `[target.'cfg(...)']` for rustc and rustdoc flags is buggy.
This adds meaningful tests and fixes the issue.

Fixes #3499

src/cargo/ops/cargo_rustc/context.rs
tests/rustflags.rs

index f1b113e94e82808009156bf53ba26cb385ae9eae..53358ef8c502f925b33be61fe6c380b7f2a57b22 100644 (file)
@@ -1049,11 +1049,18 @@ fn env_args(config: &Config,
     // ...including target.'cfg(...)'.rustflags
     if let Some(ref target_cfg) = target_info.cfg {
         if let Some(table) = config.get_table("target")? {
-            let cfgs = table.val.iter().map(|(t, _)| (CfgExpr::from_str(t), t))
-                .filter_map(|(c, n)| c.map(|c| (c, n)).ok())
-                .filter(|&(ref c, _)| c.matches(target_cfg));
-            for (_, n) in cfgs {
-                let key = format!("target.'{}'.{}", n, name);
+            let cfgs = table.val.keys().filter_map(|t| {
+                if t.starts_with("cfg(") && t.ends_with(")") {
+                    let cfg = &t[4..t.len() - 1];
+                    CfgExpr::from_str(cfg)
+                        .ok()
+                        .and_then(|c| if c.matches(target_cfg) { Some(t) } else { None })
+                } else {
+                    None
+                }
+            });
+            for n in cfgs {
+                let key = format!("target.{}.{}", n, name);
                 if let Some(args) = config.get_list_or_split_string(&key)? {
                     let args = args.val.into_iter();
                     rustflags.extend(args);
index 8cdd31f1ba2fb7b3efa66f647af6e53533b3c6dc..9b319b47821f121f436e65458aaace7f4accbd44 100644 (file)
@@ -958,33 +958,55 @@ fn cfg_rustflags_normal_source() {
             name = "foo"
             version = "0.0.1"
         "#)
-        .file("src/lib.rs", "")
+        .file("src/lib.rs", "pub fn t() {}")
         .file("src/bin/a.rs", "fn main() {}")
         .file("examples/b.rs", "fn main() {}")
         .file("tests/c.rs", "#[test] fn f() { }")
-        .file("benches/d.rs", r#"
-            #![feature(test)]
-            extern crate test;
-            #[bench] fn run1(_ben: &mut test::Bencher) { }"#)
-        .file(".cargo/config", "
-            [target.'cfg(feature=\"feat\")']
-            rustflags = [\"-Z\", \"bogus\"]
-            ");
+        .file(".cargo/config", &format!(r#"
+            [target.'cfg({})']
+            rustflags = ["--cfg", "bar"]
+            "#, if rustc_host().contains("-windows-") {"windows"} else {"not(windows)"}));
     p.build();
-
-    assert_that(p.cargo("build").arg("--features").arg("\"feat\"")
-                .arg("--lib"),
-                execs().with_status(101));
-    assert_that(p.cargo("build").arg("--features").arg("\"feat\"")
-                .arg("--bin=a"),
-                execs().with_status(101));
-    assert_that(p.cargo("build").arg("--features").arg("\"feat\"")
-                .arg("--example=b"),
-                execs().with_status(101));
-    assert_that(p.cargo("test").arg("--features").arg("\"feat\""),
-                execs().with_status(101));
-    assert_that(p.cargo("bench").arg("--features").arg("\"feat\""),
-                execs().with_status(101));
+    
+    assert_that(p.cargo("build").arg("--lib").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+"));
+    
+    assert_that(p.cargo("build").arg("--bin=a").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+"));
+    
+    assert_that(p.cargo("build").arg("--example=b").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+"));
+    
+    assert_that(p.cargo("test").arg("--no-run").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[RUNNING] `rustc [..] --cfg bar[..]`
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+"));
+    
+    assert_that(p.cargo("bench").arg("--no-run").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[RUNNING] `rustc [..] --cfg bar[..]`
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] release [optimized] target(s) in [..]
+"));
+                
 }
 
 // target.'cfg(...)'.rustflags takes precedence over build.rustflags
@@ -996,32 +1018,59 @@ fn cfg_rustflags_precedence() {
             name = "foo"
             version = "0.0.1"
         "#)
-        .file("src/lib.rs", "")
-        .file(".cargo/config", "
+        .file("src/lib.rs", "pub fn t() {}")
+        .file("src/bin/a.rs", "fn main() {}")
+        .file("examples/b.rs", "fn main() {}")
+        .file("tests/c.rs", "#[test] fn f() { }")
+        .file(".cargo/config", &format!(r#"
             [build]
-            rustflags = [\"--cfg\", \"foo\"]
+            rustflags = ["--cfg", "foo"]
 
-            [target.'cfg(feature = \"feat\"')]
-            rustflags = [\"-Z\", \"bogus\"]
-            ");
+            [target.'cfg({})']
+            rustflags = ["--cfg", "bar"]
+            "#, if rustc_host().contains("-windows-") { "windows" } else { "not(windows)" }));
     p.build();
 
-    assert_that(p.cargo("build").arg("--features").arg("\"feat\"")
-                .arg("--lib"),
-                execs().with_status(101));
-    assert_that(p.cargo("build").arg("--features").arg("\"feat\"")
-                .arg("--bin=a"),
-                execs().with_status(101));
-    assert_that(p.cargo("build").arg("--features").arg("\"feat\"")
-                .arg("--example=b"),
-                execs().with_status(101));
-    assert_that(p.cargo("test").arg("--features").arg("\"feat\""),
-                execs().with_status(101));
-    assert_that(p.cargo("bench").arg("--features").arg("\"feat\""),
-                execs().with_status(101));
-}
+    assert_that(p.cargo("build").arg("--lib").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+"));
+
+    assert_that(p.cargo("build").arg("--bin=a").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+"));
+
+    assert_that(p.cargo("build").arg("--example=b").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+"));
 
+    assert_that(p.cargo("test").arg("--no-run").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[RUNNING] `rustc [..] --cfg bar[..]`
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+"));
 
+    assert_that(p.cargo("bench").arg("--no-run").arg("-v"),
+                execs().with_status(0).with_stderr("\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] --cfg bar[..]`
+[RUNNING] `rustc [..] --cfg bar[..]`
+[RUNNING] `rustc [..] --cfg bar[..]`
+[FINISHED] release [optimized] target(s) in [..]
+"));
+                
+}
 
 #[test]
 fn target_rustflags_string_and_array_form1() {